package com.aidansmeaton.weightmanager;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.aidansmeaton.weightmanager.util.TimeFormatter;
import com.quietlycoding.android.picker.NumberPicker;

/** The first activity in the app. */
public class SetUpTargetWeightActivity extends Activity {

	private static final int TARGET = 0;
	private final int DEFAULT_TARGET_DISTANCE = 3;
	private final float POUNDS_IN_KILO = 2.2f;
	private final float KILOS_IN_POUND = 0.4536f;
	private final int POUNDS_IN_STONE = 14;
	private final int MAX_POUNDS = 13;
	private final int MAX_STONES = 99;
	private final int MAX_KILOS = 199;
	private final int MIN_POUNDS = 0;
	private final int MIN_STONES = 0;
	private final int MIN_KILOS = 0;

	private Calendar targetDate;
	private String start_date;
	private String target_date;
	private int start_weight;
	private int target_weight;
	private boolean imperial;

	private Button targetDateButton;
	private NumberPicker targetStonesPicker;
	private NumberPicker targetPoundsPicker;
	private NumberPicker targetKilosPicker;
	
	private LinearLayout imperialView;
	private LinearLayout metricView;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.setup_target_weight);

		setTitle("Setup - Target");

		targetDate = Calendar.getInstance();
		imperial = getSharedPreferences("Profile", 0).getBoolean("Imperial",true);

		targetStonesPicker = (NumberPicker) findViewById(R.id.target_stones_picker);
		targetPoundsPicker = (NumberPicker) findViewById(R.id.target_pounds_picker);
		targetKilosPicker = (NumberPicker) findViewById(R.id.target_kg_picker);
		
		start_weight = getSharedPreferences("Profile", 0).getInt("StartWeight",0);
		start_date = getSharedPreferences("Profile", 0).getString("StartDate", TimeFormatter.getDatabaseDateString(Calendar.getInstance()));
		
		boolean start_units_imperial = getSharedPreferences("Profile", 0).getBoolean("StartUnits",imperial);
		// convert metric start weight to imperial
		if (imperial && !start_units_imperial){
			start_weight = ((int)(start_weight * POUNDS_IN_KILO));
		}
		// convert imperial start weight to metric
		if (!imperial && start_units_imperial){
			start_weight = ((int)(start_weight * KILOS_IN_POUND));
		}

		target_weight = getSharedPreferences("Profile", 0).getInt("TargetWeight", adjustWeight(start_weight, 0.95f));
		target_date = getSharedPreferences("Profile", 0).getString("TargetDate", adjustDate(start_date, Calendar.MONTH, DEFAULT_TARGET_DISTANCE));
		
		boolean target_units_imperial = getSharedPreferences("Profile", 0).getBoolean("TargetUnits",imperial);
		// convert metric start weight to imperial
		if (imperial && !target_units_imperial){
			target_weight = ((int)(target_weight * POUNDS_IN_KILO));
		}
		// convert imperial start weight to metric
		if (!imperial && target_units_imperial){
			target_weight = ((int)(target_weight * KILOS_IN_POUND));
		}
		
		imperialView = (LinearLayout) findViewById(R.id.imperial);
		metricView = (LinearLayout) findViewById(R.id.metric);
		
		// Imperial
		if (imperial){
			metricView.setVisibility(View.GONE);
			imperialView.setVisibility(View.VISIBLE);
			targetDateButton = (Button) findViewById(R.id.target_date_imperial);
			targetStonesPicker.setRange(MIN_STONES, MAX_STONES);
			targetPoundsPicker.setRange(MIN_POUNDS, MAX_POUNDS);
			targetStonesPicker.setCurrent((start_weight - target_weight) / POUNDS_IN_STONE);
			targetPoundsPicker.setCurrent((start_weight - target_weight) % POUNDS_IN_STONE);
		}
		
		// Metric
		else {
			metricView.setVisibility(View.VISIBLE);
			imperialView.setVisibility(View.GONE);
			targetDateButton = (Button) findViewById(R.id.target_date_metric);
			targetKilosPicker.setRange(MIN_KILOS, MAX_KILOS);
			targetKilosPicker.setCurrent(start_weight - target_weight);
		}
		
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		try {
			targetDate.setTime(formatter.parse(target_date));
		} catch (ParseException e) {
			e.printStackTrace();
		}
		updateDisplay(); // date buttons

		// Stop keyboard popping up automatically
		getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

	}
	
	public void targetDateClick(View v) {
		showDialog(TARGET);
	}	
	
	public void calculateClick(View v){
		target_weight = adjustWeight(start_weight, 0.95f);
		target_date = adjustDate(start_date, Calendar.MONTH, DEFAULT_TARGET_DISTANCE);
		if (imperial) {
			targetStonesPicker.setCurrent((start_weight - target_weight) / POUNDS_IN_STONE);
			targetPoundsPicker.setCurrent((start_weight - target_weight) % POUNDS_IN_STONE);
		} else {
			targetKilosPicker.setCurrent(start_weight - target_weight);
		}
		Toast.makeText(this, "5% of your start weight", Toast.LENGTH_SHORT).show();
	}
	
	private int adjustWeight(int weight, float percent){
		return (int) ((float) weight * percent);
	}
	
	private String adjustDate(String date, int field, int value){
		Calendar c = Calendar.getInstance();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		try {
			c.setTime(formatter.parse(date));
			c.add(field, value);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return TimeFormatter.getDatabaseDateString(c);
	}	

	private void updateDisplay() {
		targetDateButton.setText(new StringBuilder()
				.append(TimeFormatter.getDayAsString(targetDate
						.get(Calendar.DAY_OF_WEEK)))
				.append(" ")
				.append(targetDate.get(Calendar.DAY_OF_MONTH))
				.append(" ")
				.append(TimeFormatter.getMonthAsString(targetDate
						.get(Calendar.MONTH))).append(" ")
				.append(targetDate.get(Calendar.YEAR)));
	}

	@Override
	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case (TARGET):
			return new DatePickerDialog(this, targetDateSetListener,
					targetDate.get(Calendar.YEAR),
					targetDate.get(Calendar.MONTH),
					targetDate.get(Calendar.DAY_OF_MONTH));
		}
		return null;
	}

	// the callback received when the user "sets" the date in the dialog
	private DatePickerDialog.OnDateSetListener targetDateSetListener = new DatePickerDialog.OnDateSetListener() {
		public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
			targetDate.set(Calendar.YEAR, year);
			targetDate.set(Calendar.MONTH, monthOfYear);
			targetDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
			updateDisplay();
		}
	};

	private boolean saveTargetWeight() {
		
		// get weights and dates from widgets
		boolean success = true;
		String targetDateString = TimeFormatter.getDatabaseDateString(targetDate);
		int targetWeight = (imperial)
			? start_weight - ((targetStonesPicker.getCurrent() * POUNDS_IN_STONE) + targetPoundsPicker.getCurrent())
			: start_weight - targetKilosPicker.getCurrent();
		
		// input validation
		try {
			if (targetWeight <= 0) throw (new NumberFormatException("Invalid weight"));
			if (targetDateString.compareTo(start_date) <= 0) throw (new NumberFormatException("Invalid date"));
			
		// catch invalid input
		} catch (NumberFormatException e) {
			success = false;
			if (e.getMessage().equals("Invalid weight"))
				Toast.makeText(this, "Please lower the weight you wish to lose.", Toast.LENGTH_LONG).show();
			if (e.getMessage().equals("Invalid date"))
				Toast.makeText(this, "Please select a date in the future.",	Toast.LENGTH_SHORT).show();
		}
		
		// save if valid input
		if (success) {
			getSharedPreferences("Profile", 0).edit().putInt("TargetWeight", targetWeight).commit();
			getSharedPreferences("Profile", 0).edit().putString("TargetDate", targetDateString).commit();
			getSharedPreferences("Profile", 0).edit().putBoolean("TargetUnits", imperial).commit();
		}
		
		return success;
	}

	public void nextClick(View v) {
		if (saveTargetWeight()) {
			finish();
			Intent setupIntent = new Intent(this, SetUpGoalsActivity.class);
			this.startActivity(setupIntent);
		}
	}

	public void backClick(View v) {
		saveTargetWeight();
		finish();
		Intent setupIntent = new Intent(this, SetUpStartWeightActivity.class);
		this.startActivity(setupIntent);
	}

	public void laterClick(View v) {
		finish();
	}

}